﻿/**	@file		iris_inst.h
 *	@date		(2008-09-28 13:55:28)/(2012-01-01 20:33:27)
 *-----------------------------------------------------------------------------
 *	@version	1.0.19.29
 *	@author		Nick Shallery	(nicknide@gmail.com)
 *	@copyright	YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.
 *-----------------------------------------------------------------------------
**/

#if			!defined(__LXIRIS__IRIS_INST__H__NICK__K_IN_G__)
#define		__LXIRIS__IRIS_INST__H__NICK__K_IN_G__
//==============================================================================
//--------------------------------------------------------------------------
#if			!defined(__LOLIX_LXIRIS__IRIS_TYPE__H__NICK__K_IN_G__)
	#include	"./iris_type.h"
#endif	//	!defined(__LOLIX_LXIRIS__IRIS_TYPE__H__NICK__K_IN_G__)

#if			!defined(__LOLIX__LOLIX_INSTANCE__K_IN_G__)
	#include	"../../lolix/lolix_inst.h"
#endif	//	!defined(__LOLIX__LOLIX_INSTANCE__K_IN_G__)

#if			!defined(__LOLIX__TOY__INVOKE_CAST__HPP__K_IN_G__)
	#include	"../../lolix/toy/invoke_cast.hpp"
#endif	//	!defined(__LOLIX__TOY__INVOKE_CAST__HPP__K_IN_G__)

namespace lolix{namespace pretty{class canvas;class canvas_package;class render_texture;}}

namespace lxiris{

enum ENUM_MSG_TYPE;
struct SMsgTypeMouseStatus;

union	iris_flag
{
	typedef lolix::lx_u32 flag_type;
	LOLIX_INLINE_CALL	iris_flag(void){}
	LOLIX_INLINE_CALL	iris_flag(flag_type u): iflag(u){}
	struct
	{
		flag_type	opt_resize	: 1;	//	处理 resize 指令
		flag_type	opt_msg		: 1;	//	处理 消息
		flag_type	opt_render	: 1;	//	处理 渲染
		flag_type	opt_reserve	:13;	//	保留

		flag_type	dock		: 1;
		flag_type	no_catch	: 1;	//	不允许缓冲该对象
		flag_type	catch_paint	: 1;	//	缓存子对象的绘制: iris_frame 有效
	};

	struct
	{
		flag_type	opt_mask	:32;
	};
	flag_type	iflag;
};


class	LOLIX_NO_VTABLE	iris
	: public lolix::itf
{
public:
	LOLIX_DECLARE_ITF(lxiris::iris, lolix::itf, (0xb6cb1d0f, 0xb0f44147, 0xa962c8da, 0x21795563));


	typedef lolix::pretty::canvas					paper;

	struct iris_info
	{
		iris_rect	wnd_rect;
		iris*		iris_ptr;
	};

	LOLIX_INTERFACE(get_flag, void, (iris_flag* flag)const);
	LOLIX_INTERFACE(set_flag, void, (iris_flag flag));

	LOLIX_INTERFACE(post_msg, lolix::LOLIX_RETNV	, (ENUM_MSG_TYPE msg_type, const void*));

	//===========================================================================
	//	得到当前显示用的版本
	//---------------------------------------------------------------------------
	//		@:当前的数据版本
	//---------------------------------------------------------------------------
	//	当内部数据更新的时候必须更新该版本, 来通知上层数据有更新,需要重新绘制
	//===========================================================================
	LOLIX_INTERFACE(show_ver, lolix::size_type, (void)const);

	//===========================================================================
	//	绘制到渲染上下文中
	//---------------------------------------------------------------------------
	//	pp			[i ] :	渲染目标
	//	cur_rect	[i ] :	当前窗口目标区域
	//	aspect		[i ] :	纵横比 (w/h)
	//	canp		[i ] :	当前渲染上下文
	//===========================================================================
	LOLIX_INTERFACE(paint	, void, (paper* pp, const iris_rect* cur_rect, float aspect, lolix::pretty::canvas_package* canp));

	//===========================================================================
	//	此对象以后不会再被绘制.
	//---------------------------------------------------------------------------
	//	recursion	[i ] :	是否递归此方法
	//---------------------------------------------------------------------------
	//	!仅绘制线程可以调用此函数, 否则无法保证显示资源的正确释放
	//===========================================================================
	LOLIX_INTERFACE(dissolve, void, (bool recursion));

	//===========================================================================
	//	测试给定的坐标是否处于自己的范围
	//---------------------------------------------------------------------------
	//	x			[i ] :	相对于自身的 x 值
	//	y			[i ] :	相对于自身的 y 值
	//---------------------------------------------------------------------------
	//	@	true)	在内部
	//		false)	不在内部
	//===========================================================================
	LOLIX_INTERFACE(hit		, bool,	(float x, float y, float aspect)const);

	LOLIX_INTERFACE(set_udat	, void, (void* usr_dat));
	LOLIX_INTERFACE(get_udat	, void*, (void)const);

	LOLIX_INTERFACE(on_attach	, void, (bool is_attach, iris* base));
	LOLIX_INTERFACE(on_presize	, void,	(iris_size const* oldSize, iris* base));

	#pragma	region 辅助函数相关
	template<size_type dim>
	LOLIX_INLINE_CALL void size(lolix::lx_u32 (&xy)[dim])const
		{
		STATIC_ASSERT(dim >= 2);
		return size((iris_size*)xy);
		}
	#pragma endregion
};


class LOLIX_NO_VTABLE iris_frame
	: public iris
{
public:
	LOLIX_DECLARE_ITF(lxiris::iris_frame, lxiris::iris, (0x417bc15e, 0x366644d1, 0xaf8dc78a, 0xc0d29b04));


	LOLIX_INTERFACE(set_size, lolix::LOLIX_RETNV	, (iris_rect const* ir));

	LOLIX_INTERFACE(flush_flag, void, (void));

	//	Attrib
	LOLIX_INTERFACE(chr_size, size_type, (void)const);
	//===========================================================================
	//	获得子窗口
	//---------------------------------------------------------------------------
	//	out_ptr		[ o] :	返回的子窗口信息
	//	from		[i ] :	从多少开始
	//	to			[i ] :	到多少个
	//---------------------------------------------------------------------------
	//	@rtv	:	该区间里存在多少条数据项
	//---------------------------------------------------------------------------
	//	如果 to > 子窗口索引， 则到最后
	//===========================================================================
	LOLIX_INTERFACE(get_chr	, size_type, (iris_info* out_ptr, size_type from, size_type to));

	//===========================================================================
	//	插入子节点
	//---------------------------------------------------------------------------
	//	ir			[i ] :	需要插入的子节点, 如果当前节点已经插入，则更新矩阵
	//	wnd_rect	[i ] :	相对当前此窗口的比例
	//===========================================================================
	LOLIX_INTERFACE(ist_chr	, void, (iris* ir, iris_rect const* wnd_rect));
	LOLIX_INTERFACE(rmv_chr	, void, (iris*));

	#pragma	region 辅助函数相关
	LOLIX_INLINE_CALL void clr_chr(void)
		{
		iris_info one;
		while ( get_chr(&one, 0, 1) )
			this->rmv_chr(one.iris_ptr);
		}
	#pragma endregion
};


class LOLIX_NO_VTABLE iris_image
	: public iris
{
public:
	enum ENUM_IMG_FILL_TYPE
	{	IMG_FILL_TYPE_ALL			//	填充满
	,	IMG_FILL_TYPE_LOCK_ASPECT	//	锁定纵横比
	};
	enum ENUM_ALPHA_MODEL
	{	ALPHA_MODEL_NO_USED
	,	ALPHA_MODEL_TEST
	,	ALPHA_MODEL_BLEND
	//,	ALPHA_MODEL_USE_SELF
	//,	ALPHA_MODEL_MULTI_IMG_AND_SELF
	,	_ALPHA_MODEL_CNT
	,	_ALPHA_MODEL_VER	= 1
	};

	enum ENUM_UV_WRAP_TYPE
	{	UV_WRAP_TYPE_OVERLAPED		//	延伸
	,	UV_WRAP_TYPE_CLAMP			//	钳制在[0, 1]范围上
	,	UV_WRAP_TYPE_REPEAT			//	循环
	,	UV_WRAP_TYPE_MIRROR_REPEAT	//	镜像循环
	};

	LOLIX_DECLARE_ITF(lxiris::iris_image, lxiris::iris, (0xca248218, 0x41d84546, 0x9a80cd33, 0xdabf430c));
	//===========================================================================
	//	set_img
	//---------------------------------------------------------------------------
	//	@rtex	[i ]	: 设定用来渲染的图片
	//	@rect	[i ] =0	: 设定用来渲染的图片区域：如果为0表示使用全部图片
	//===========================================================================
	LOLIX_INTERFACE(set_img		, lolix::LOLIX_RETNV, (lolix::pretty::render_texture* rtex, lxiris::iris_rect const* rect /*xy = start-st, zw = end-st*/));
	LOLIX_INTERFACE(query_img	, lolix::LOLIX_RETNV, (lolix::pretty::render_texture**));
	LOLIX_INTERFACE(get_uv		, void				, (lxiris::iris_rect* rect)const);
	LOLIX_INTERFACE(set_uv		, lolix::LOLIX_RETNV, (lxiris::iris_rect const* rect));
	LOLIX_INTERFACE(get_filltype, ENUM_IMG_FILL_TYPE, (void)const);
	LOLIX_INTERFACE(set_filltype, void				, (ENUM_IMG_FILL_TYPE set_type));
	LOLIX_INTERFACE(get_alp_mode, ENUM_ALPHA_MODEL	, (void)const);
	LOLIX_INTERFACE(set_alp_mode, void				, (ENUM_ALPHA_MODEL));
	LOLIX_INTERFACE(get_alp_val	, float				, (void)const);
	LOLIX_INTERFACE(set_alp_val	, void				, (float alpha_mult));
	//===========================================================================
	//	获得当前的回绕模式
	//---------------------------------------------------------------------------
	//	@prev_u_type	[i ] =0	:	内部U
	//	@prev_v_type	[i ] =0	:	内部V
	//	@after_u_type	[i ] =0	:	全局U
	//	@after_v_type	[i ] =0	:	全局V
	//===========================================================================
	LOLIX_INTERFACE(get_wrap	, void				, (ENUM_UV_WRAP_TYPE* prev_u_type, ENUM_UV_WRAP_TYPE* prev_v_type, ENUM_UV_WRAP_TYPE* after_u_type, ENUM_UV_WRAP_TYPE* after_v_type)const);
	LOLIX_INTERFACE(set_wrap	, lolix::LOLIX_RETNV, (ENUM_UV_WRAP_TYPE prev_u_type, ENUM_UV_WRAP_TYPE prev_v_type, ENUM_UV_WRAP_TYPE after_u_type, ENUM_UV_WRAP_TYPE after_v_type));
};


class LOLIX_NO_VTABLE iris_button
	: public iris_image
{
public:
	LOLIX_DECLARE_ITF(lxiris::iris_button, lxiris::iris_image, (0xed36fab1, 0x743944b3, 0x9185a9c9, 0xf49d87f3));
	typedef lolix::toy::invoker_process<void, false, lolix::toy::type_list<const SMsgTypeMouseStatus&, iris_button*> >	click_process;
	typedef lolix::toy::invoker_process<void, false, lolix::toy::type_list<iris_button*> >	enter_process;
	typedef lolix::toy::invoker_process<void, false, lolix::toy::type_list<iris_button*> >	leave_process;

	STATIC_ASSERT(sizeof(click_process) == 2*sizeof(size_type));
	LOLIX_INTERFACE(set_fn_click, void, (click_process));
	LOLIX_INTERFACE(set_fn_enter, void, (enter_process));
	LOLIX_INTERFACE(set_fn_leave, void, (leave_process));

	template<typename _Ty>
	LOLIX_INLINE_CALL void set_fn_click(_Ty* ty, void (LOLIX_CALL _Ty::*fn)(const SMsgTypeMouseStatus&, iris_button*))
		{ return this->set_fn_click(click_process(ty, fn)); }
};

}



//--------------------------------------------------------------------------
//==============================================================================
#endif	//	!defined(__LXIRIS__IRIS_INST__H__NICK__K_IN_G__)
